package logger

import (
	"bytes"
	"log"
	"time"

	"github.com/gin-gonic/gin"

	"go-toy/middleware/logger/common"
	loggerInterface "go-toy/middleware/logger/interf"
)

type ResponseWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w *ResponseWriter) Write(b []byte) (int, error) {
	w.body.Write(b) // save the response body in the buffer
	return w.ResponseWriter.Write(b)
}

type GoWriter struct {
}

// Return the gin.HandlerFunc for the middleware program
func (w *GoWriter) Handle() gin.HandlerFunc {
	// Create the log file
	// file := common.FileIntance.CreatedFile()
	// logger := log.New(file, "", log.LstdFlags|log.Llongfile)

	// Create the rolling log file
	lumberJackLogger := common.RollingIntance.Build()
	logger := log.New(lumberJackLogger, "", log.LstdFlags|log.Llongfile)
	// logger.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
	// loger.SetPrefix("Request:")

	return func(gc *gin.Context) {
		// TODO: write log to any where
		customWriter := common.ResponseWriter{
			ResponseWriter: gc.Writer,
			Body:           bytes.NewBufferString(""),
		}
		gc.Writer = &customWriter

		startTime := time.Now()
		gc.Next()
		endTime := time.Now()

		latency := endTime.Sub(startTime)
		statusCode := gc.Writer.Status()
		clientIP := gc.ClientIP()
		method := gc.Request.Method
		path := gc.Request.URL.Path
		responseBody := customWriter.Body.String()

		logger.Printf("| %3d | %5v | %15s | %6s | %s | %s\n",
			statusCode,
			latency,
			clientIP,
			method,
			path,
			responseBody,
		)
	}
}

var GoWriterInstance loggerInterface.Writer = &GoWriter{}
